package com.jms.web.mvc.handler;

import java.lang.reflect.Parameter;
import java.util.*;
import java.util.regex.Pattern;

/**
 * 方法处理器类，用于处理HTTP请求方法的映射和匹配
 * 该类封装了方法名、Bean名称、请求类型和URI模式等信息
 */
public class MethodHandler {
    String methodName;
    String beanName;
    String requestType;
    Pattern uriPattern;
    Parameter[] parameters;
    Class<?>[] parameterTypes;
    List<String> pathVariableNames;

    public Class<?>[] getParameterTypes() {
        return parameterTypes;
    }

    public void setParameterTypes(Class<?>[] parameterTypes) {
        this.parameterTypes = parameterTypes;
    }

    public Pattern getUriPattern() {
        return uriPattern;
    }

    public List<String> getPathVariableNames() {
        return pathVariableNames;
    }

    /**
     * 构造方法，创建MethodHandler实例
     * @param methodName 方法名称
     * @param beanName Bean名称
     * @param requestType 请求类型（如GET、POST等）
     * @param uri URI路径
     */
    public MethodHandler(String methodName, String beanName, String requestType, String uri, Parameter[] parameters) {
        this.methodName = methodName;
        this.beanName = beanName;
        this.requestType = requestType;
        this.parameters = parameters;
        this.parameterTypes = Arrays.stream(parameters).map(Parameter::getType).toArray(Class[]::new);
        pathVariableNames = new ArrayList<>();
        buildUriPattern(uri);
    }

    private void buildUriPattern(String uri) {
        // 标准化URI路径
        String normalizedUri = normalizeUri(uri);

        // 处理根路径的情况
        if (normalizedUri.isEmpty()) {
            this.pathVariableNames = new ArrayList<>();
            this.uriPattern = Pattern.compile("^/$"); // 只匹配根路径
            return;
        }

        String[] uriSegments = normalizedUri.split("/");
        StringBuilder patternBuilder = new StringBuilder();
        patternBuilder.append("^/"); // 以/开始
        List<String> variableNames = new ArrayList<>();

        for (int i = 0; i < uriSegments.length; i++) {
            if (i > 0) patternBuilder.append("/");

            String segment = uriSegments[i];
            if ("*".equals(segment)) {
                patternBuilder.append(".*");
            } else if (segment.startsWith("{") && segment.endsWith("}")) {
                // 解析路径变量，支持 {name} 和 {name:regex} 格式
                String content = segment.substring(1, segment.length() - 1);
                String[] parts = content.split(":", 2);
                String variableName = parts[0];
                String regex = parts.length > 1 ? parts[1] : "[^/]*";

                variableNames.add(variableName);
                patternBuilder.append("(").append(regex).append(")");
            } else {
                patternBuilder.append(Pattern.quote(segment)); // 转义特殊字符
            }
        }

        patternBuilder.append("/?$"); // 可选的结尾斜杠

        this.pathVariableNames = variableNames;
        this.uriPattern = Pattern.compile(patternBuilder.toString());
    }

    /**
     * 标准化URI路径
     * @param uri 原始URI
     * @return 标准化后的URI
     */
    private String normalizeUri(String uri) {
        if (uri == null) {
            return "";
        }

        String normalized = uri.trim();

        // 处理特殊情况
        if (normalized.equals("/") || normalized.isEmpty()) {
            return "";
        }

        // 移除开头的斜杠（我们会在正则表达式中添加）
        if (normalized.startsWith("/")) {
            normalized = normalized.substring(1);
        }

        // 移除结尾的斜杠
        if (normalized.endsWith("/")) {
            normalized = normalized.substring(0, normalized.length() - 1);
        }

        return normalized;
    }


    /**
     * 匹配给定的URI是否符合当前处理器的URI模式
     * @param uri 待匹配的URI
     * @return 如果匹配成功返回true，否则返回false
     */
    public boolean matcher(String uri) {
        return uriPattern.matcher(uri).matches();
    }

    /**
     * 获取方法名称
     * @return 方法名称
     */
    public String getMethodName() {
        return methodName;
    }

    /**
     * 设置方法名称
     * @param methodName 方法名称
     */
    public void setMethodName(String methodName) {
        this.methodName = methodName;
    }

    /**
     * 获取Bean名称
     * @return Bean名称
     */
    public String getBeanName() {
        return beanName;
    }

    /**
     * 设置Bean名称
     * @param beanName Bean名称
     */
    public void setBeanName(String beanName) {
        this.beanName = beanName;
    }

    /**
     * 获取请求类型
     * @return 请求类型
     */
    public String getRequestType() {
        return requestType;
    }

    /**
     * 设置请求类型
     * @param requestType 请求类型
     */
    public void setRequestType(String requestType) {
        this.requestType = requestType;
    }

    public Parameter[] getParameters() {
        return parameters;
    }

    public void setParameters(Parameter[] parameters) {
        this.parameters = parameters;
    }
}

